#include <iostream>
#include <ctime>
#include <cstdlib>
// clear && g++ 指针引用速览.cpp -o hello_fltk `fltk-config --cxxflags --ldflags` && ./hello_fltk

using namespace std;

int LWF();
int pointer_null();
int incremental_pointer();
int decreasing_pointer();
int compare_pointer();
int pointer_array();
int multi_level_indirect_addressing();
int function_pointer();
// 在写函数时应习惯性的先声明函数，然后再定义函数
void getSeconds(unsigned long *par);
// 函数声明
double getAverage(int *arr, int size);
int *getRandom();
int testquote();
// 函数声明
void swap(int &x, int &y);
int quote_parameter();
double &setValues(int i);

const int MAX = 3;

int main()
{
    int lwf, PN, IP, DP, CP, PA, MLIA, FP, TQ, QP;
    lwf = LWF();
    PN = pointer_null();
    IP = incremental_pointer();
    DP = decreasing_pointer();
    CP = compare_pointer();
    PA = pointer_array();
    MLIA = multi_level_indirect_addressing();
    FP = function_pointer();
    TQ = testquote();
    QP = quote_parameter();
    return 0;
}

int LWF()
{
    int var = 20; // 实际变量的声明
    int *ip;      // 指针变量的声明
    ip = &var;    // 在指针变量中存储 var 的地址
    cout << "Value of var variable: ";
    cout << var << endl;
    cout << "Address stored in ip variable: ";
    cout << ip << endl; // 输出在指针变量中存储的地址
    cout << "Value of *ip variable: ";
    cout << *ip << endl; // 访问指针中地址的值
    return 0;
}

int pointer_null()
{
    int *ptr = NULL;
    cout << "ptr 的值是 " << ptr << endl;
    return 0;
}
int incremental_pointer()
{
    int arr[] = {10, 20, 30, 40, 50};               // 定义一个数组
    int *ptr = arr;                                 // 输出指针指向的元素
    cout << "指针当前地址: " << ptr << endl;        // 递增指针
    cout << "指针当前指向的元素: " << *ptr << endl; // 递增指针
    ptr++;
    cout << "指针当前地址: " << ptr << endl;          // 递增指针
    cout << "递增指针后指向的元素: " << *ptr << endl; // 输出指针指向的元素
    return 0;
}
int decreasing_pointer()
{
    int arr[] = {10, 20, 30, 40, 50};                 // 定义一个数组
    int *ptr = &arr[3];                               // 定义一个指向数组第二个元素的指针
    cout << "指针当前地址: " << ptr << endl;          // 输出指针当前指向的元素
    cout << "指针当前指向的元素: " << *ptr << endl;   // 输出指针当前指向的元素
    ptr--;                                            // 递减指针
    cout << "递减指针后指向的元素: " << *ptr << endl; // 输出指针递减后指向的元素
    return 0;
}
int compare_pointer()
{
    int arr[] = {10, 20, 30, 40, 50};
    int *ptr1 = &arr[1]; // 指向数组的第二个元素
    int *ptr2 = &arr[3]; // 指向数组的第四个元素

    // 比较指针的相对位置
    if (ptr1 < ptr2)
    {
        cout << "ptr1 指向的元素在 ptr2 指向的元素之前" << endl;
    }
    else
    {
        cout << "ptr1 指向的元素不在 ptr2 指向的元素之前" << endl;
    }

    if (ptr2 > ptr1)
    {
        cout << "ptr2 指向的元素在 ptr1 指向的元素之后" << endl;
    }
    else
    {
        cout << "ptr2 指向的元素不在 ptr1 指向的元素之后" << endl;
    }

    int *ptr3 = &arr[1]; // 指向数组的第二个元素

    // 相等性比较
    if (ptr1 == ptr3)
    {
        cout << "ptr1 和 ptr3 指向相同的位置" << endl;
    }
    else
    {
        cout << "ptr1 和 ptr3 指向不同的位置" << endl;
    }

    if (ptr1 != ptr2)
    {
        cout << "ptr1 和 ptr2 指向不同的位置" << endl;
    }
    else
    {
        cout << "ptr1 和 ptr2 指向相同的位置" << endl;
    }

    return 0;
}
int pointer_array()
{
    int var[MAX] = {10, 100, 200};
    int *ptr;
    *(var + 2) = 500;
    // 指针中的数组地址
    ptr = var; // 数组赋予指针，不需要使用&，即可获得地址
    for (int i = 0; i < MAX; i++)
    {
        cout << "var[" << i << "]的内存地址为 ";
        cout << ptr << endl;

        cout << "var[" << i << "] 的值为 " << *ptr << endl;

        // 移动到下一个位置
        ptr++;
    }

    int *ptr1[MAX];
    for (int i = 0; i < MAX; i++)
    {
        ptr1[i] = &var[i]; // 赋值为整数的地址
    }
    for (int i = 0; i < MAX; i++)
    {
        cout << "Value of var[" << i << "] = ";
        cout << *ptr1[i] << endl;
    }

    const char *names[MAX] = {
        "Zara Ali",
        "Hina Ali",
        "Nuha Ali",
    };
    for (int i = 0; i < MAX; i++)
    {
        cout << "Value of names[" << i << "] = ";
        cout << names[i] << endl;
    }
    return 0;
}
int multi_level_indirect_addressing()
{
    int var;
    int *ptr;
    int **pptr;
    var = 3000;
    // 获取 var 的地址
    ptr = &var;
    // 使用运算符 & 获取 ptr 的地址
    pptr = &ptr;
    // 使用 pptr 获取值
    cout << "var 值为 :" << var << endl;
    cout << "*ptr 地址：" << ptr << " 值为:" << *ptr << endl;
    cout << "**pptr 地址：" << pptr << " 值为:" << **pptr << endl;
    return 0;
}
int function_pointer()
{
    unsigned long sec;
    getSeconds(&sec);
    // 输出实际值
    cout << "Number of seconds :" << sec << endl;

    // 带有 5 个元素的整型数组
    int balance[5] = {1000, 2, 3, 17, 50};
    double avg;
    // 传递一个指向数组的指针作为参数
    avg = getAverage(balance, 5);
    // 输出返回值
    cout << "Average value is: " << avg << endl;

    // 一个指向整数的指针
    int *p;
    p = getRandom();
    for (int i = 0; i < 10; i++)
    {
        cout << "*(p + " << i << ") : ";
        cout << *(p + i) << endl;
    }
    return 0;
}
void getSeconds(unsigned long *par)
{
    // 获取当前的秒数
    *par = time(NULL);
    return;
}
double getAverage(int *arr, int size)
{
    int i, sum = 0;
    double avg;
    cout << "arr 的 value is: " << arr << endl;
    for (i = 0; i < size; ++i)
    {
        sum += arr[i];
        cout << "arr[i] value is: " << arr[i] << endl;
    }
    avg = double(sum) / size;
    return avg;
}
// 要生成和返回随机数的函数
int *getRandom()
{
    static int r[10];
    // 设置种子
    srand((unsigned)time(NULL));
    for (int i = 0; i < 10; ++i)
    {
        r[i] = rand();
        cout << r[i] << endl;
    }
    return r;
}
int testquote()
{
    // 声明简单的变量
    int i;
    double d;
    // 声明引用变量
    int &r = i;
    double &s = d;
    i = 5;
    cout << "Value of i : " << i << endl;
    cout << "Value of i reference : " << r << endl;
    d = 11.7;
    cout << "Value of d : " << d << endl;
    cout << "Value of d reference : " << s << endl;
    return 0;
}
double vals[] = {10.1, 12.6, 33.1, 24.1, 50.0};
int &getStaticRef();
int quote_parameter()
{
    // 局部变量声明
    int a = 100;
    int b = 200;
    cout << "交换前，a 的值：" << a << endl;
    cout << "交换前，b 的值：" << b << endl;
    /* 调用函数来交换值 */
    swap(a, b);
    cout << "交换后，a 的值：" << a << endl;
    cout << "交换后，b 的值：" << b << endl;

    cout << "改变前的值" << endl;
    for (int i = 0; i < 5; i++)
    {
        cout << "vals[" << i << "] = ";
        cout << vals[i] << endl;
    }
    setValues(1) = 20.23; // 改变第 2 个元素
    setValues(3) = 70.8;  // 改变第 4 个元素
    cout << "改变后的值" << endl;
    for (int i = 0; i < 5; i++)
    {
        cout << "vals[" << i << "] = ";
        cout << vals[i] << endl;
    }

    int &ref = getStaticRef(); // 获取对静态变量的引用
    cout << "初始值：" << ref << endl;
    ref = 10; // 修改静态变量的值
    cout << "修改后的值：" << ref << endl;
    cout << "再次调用函数后的值：" << getStaticRef() << endl;
    return 0;
}
// 函数定义
void swap(int &x, int &y)
{
    int temp;
    temp = x; /* 保存地址 x 的值 */
    x = y;    /* 把 y 赋值给 x */
    y = temp; /* 把 x 赋值给 y  */
    return;
}
double &setValues(int i)
{
    double &ref = vals[i];
    return ref; // 返回第 i 个元素的引用，ref 是一个引用变量，ref 引用 vals[i]
}
// 返回对静态变量的引用
int &getStaticRef()
{
    static int num = 5; // 静态变量
    return num;
}